package com.aji.wineserver.service.impl;

import com.aji.winecommon.utills.CsvUtills;
import com.aji.winecommon.utills.FileUtills;
import com.aji.winecommon.utills.SpectrumUtill;
import com.aji.winepojo.dto.WineDto;
import com.aji.winepojo.entity.Class;
import com.aji.winepojo.entity.Wine;
import com.aji.winepojo.vo.WinePreVo;
import com.aji.winepojo.vo.WineVo;
import com.aji.winepojo.vo.WineVoPlus;
import com.aji.wineserver.config.FileEnvConfig;
import com.aji.wineserver.domain.ModelData;
import com.aji.wineserver.domain.PredicateClass;
import com.aji.wineserver.mapper.WineMapper;
import com.aji.wineserver.service.ClassService;
import com.aji.wineserver.service.ModelService;
import com.aji.wineserver.service.PredicateClassService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
public class ModelServiceImpl implements ModelService {
    @Autowired
    private WineMapper wineMapper;
    @Autowired
    private FileEnvConfig fileEnvConfig;
    @Autowired
    private ClassService classService;
    @Autowired
    private PredicateClassService predicateClassService;
    @Override
    public void trainWine(String modelPath) throws IOException, InterruptedException {
        WineDto wineDto = WineDto.builder()
                .idenId(1)//只获取专家鉴定的为训练数据
                .build();
        //文件写入
        List<WineVo> wineVos = wineMapper.pageQuery(wineDto);
        CsvUtills.wCsv(modelPath+fileEnvConfig.getModelDataTrain(),wineVos,
                SpectrumUtill.getX(fileEnvConfig.getDataPath()+fileEnvConfig.getDemoFile()));
        //模型训练
        ProcessBuilder processBuilder = new ProcessBuilder(fileEnvConfig.getPythonEnv(), fileEnvConfig.getModelPyTrain(),fileEnvConfig.getModelDataTrain());
        processBuilder.directory(new File(modelPath));
        Process process = processBuilder.start();
        int exitCode = process.waitFor();
        System.out.println("模型训练执行完成，退出码：" + exitCode);
    }

    @Override
    public List<WinePreVo> identWine(List<WineVo> wineVo, ModelData modelData) throws IOException, InterruptedException {
        //文件写入
        CsvUtills.wCsv(modelData.getModelPath()+fileEnvConfig.getModelDataTest(),wineVo,
                SpectrumUtill.getX(fileEnvConfig.getDataPath()+fileEnvConfig.getDemoFile()));
        //模型预测
        ProcessBuilder processBuilder = new ProcessBuilder(fileEnvConfig.getPythonEnv(), fileEnvConfig.getModelPyTest(),fileEnvConfig.getModelDataTest());
        processBuilder.directory(new File(modelData.getModelPath()));
        Process process = processBuilder.start();
        int exitCode = process.waitFor();
        System.out.println("模型预测执行完成，退出码：" + exitCode);

        //文件读取
        List<WinePreVo> wineVoPluses = CsvUtills.csvToListTakeClass(modelData.getModelPath() + fileEnvConfig.getModelDataPre());
        List<PredicateClass> predicateClassList = new ArrayList<>();
        for (WinePreVo wineVoplus:wineVoPluses
             ) {
            WineVo wine = wineMapper.selectOne(wineVoplus.getWineName());
            LambdaQueryWrapper<Class>classLambdaQueryWrapper = new LambdaQueryWrapper<Class>()
                    .select()
                    .eq(Class::getClassName,wineVoplus.getPreClass());
            Class one = classService.getOne(classLambdaQueryWrapper);
            PredicateClass predicateClass = PredicateClass.builder()
                    .classId(one.getClassId())
                    .wineId(wine.getWineId())
                    .modelId(modelData.getId())
                    .build();
            predicateClassList.add(predicateClass);
            /*
            写入返回值
            */
            BeanUtils.copyProperties(wine,wineVoplus);
            wineVoplus.setModelName(modelData.getModelName());
        }
        //存入预测类别表
        predicateClassService.saveBatch(predicateClassList);
        //返回值
        return wineVoPluses;
    }
}
